

import type { Job } from 'node-schedule'
import { scheduleJob } from 'node-schedule'
import { useData } from './util';
import { REQUIRE, ROOT } from './tokens';
import { container } from 'tsyringe';
import { dirname, join } from 'path';
export const ScheduleJobs = new Map<string, Job>();
export const ScheduleJobRunners = new Map<string, (date: Date) => void>();

export interface ITask {
    rule: string;
    name: string;
    title: string;
    path: string;
    params: any[];
    autoStart: boolean;
    type: 'file';// 执行文件 
}
export const startTask = (task: ITask) => {
    const root = container.resolve(ROOT)
    const runner = async (fireDate: Date) => {
        const { setData: setLog } = useData(`tasks/${task.name}.json`, [])
        try {
            const r = container.resolve(REQUIRE)
            const file = join(root, task.path)
            const res = r(file, [dirname(file)])
            if (res) {
                const m = res.default;
                if (m) {
                    const res = await m(...task.params)
                    setLog({ result: res, task: task, date: fireDate })
                }
            }
        } catch (e) {
            setLog({ error: e, task: task, date: fireDate })
        }
    }
    const job = scheduleJob(task.name, task.rule, runner)
    ScheduleJobs.set(task.name, job)
    ScheduleJobRunners.set(task.name, runner)
}
export const startTaskByName = (name: string) => {
    const { data: tasks } = useData<ITask[]>('tasks.json', [])
    const task = tasks.find(it => it.name === name)
    if (task) startTask(task)
}

export const startAutoTask = () => {
    const { data: tasks } = useData<ITask[]>('tasks.json', [])
    tasks.map(task => {
        if (task.autoStart) {
            startTask(task)
        }
    })
}

export const stopAllTask = () => {
    ScheduleJobs.forEach(job => {
        job.cancel()
    })
    ScheduleJobs.clear();
    ScheduleJobRunners.clear();
}

export const stopTask = (name: string) => {
    const job = ScheduleJobs.get(name)
    if (job) {
        job.cancel();
        ScheduleJobs.delete(name)
        ScheduleJobRunners.delete(name)
    }
}